package com.witframework.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 字符串操作工具类
 *
 * @author wuxinyang
 *
 */
public class StringTools {
	private StringTools() {
	}
	/**
	 * html实体的一个小子集。完整的可参见：http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entities_in_HTML
	 */
	private static HashMap<String,String> htmlEntities;
	  static {
	    htmlEntities = new HashMap<String,String>();
	    htmlEntities.put("&lt;","<");
	    htmlEntities.put("&gt;",">");
	    htmlEntities.put("&amp;","&");
	    htmlEntities.put("&quot;","\"");
	    htmlEntities.put("&nbsp;"," ");
	}

	/**
	 * hide latin characters
	 *
	 * @param text
	 * @return -string
	 */
	public static String hideLatinCharacters(String text) {
		text = text.replace('\301', 'A');
		text = text.replace('\311', 'E');
		text = text.replace('\315', 'I');
		text = text.replace('\323', 'O');
		text = text.replace('\332', 'U');
		text = text.replace('\341', 'a');
		text = text.replace('\351', 'e');
		text = text.replace('\355', 'i');
		text = text.replace('\363', 'o');
		text = text.replace('\372', 'u');
		text = text.replace('\361', '_');
		String regex = "[^a-zA-Z0-9-_$/\277?\241!.,;: #@()/+/**]";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(text);
		String replacement = "_";
		String result = matcher.replaceAll(replacement);
		return result;
	}
	public static String toStringOrEmpty(String src){
		if(src==null)
			return "";
		return src;
	}
	// 转unicode
	public static String convert(String str) {
		String tmp;
		StringBuffer sb = new StringBuffer(1000);
		char c;
		int i, j;
		sb.setLength(0);
		for (i = 0; i < str.length(); i++) {
			c = str.charAt(i);
			if (c > 255) {
				sb.append("\\u");
				j = (c >>> 8);
				tmp = Integer.toHexString(j);
				if (tmp.length() == 1)
					sb.append("0");
				sb.append(tmp);
				j = (c & 0xFF);
				tmp = Integer.toHexString(j);
				if (tmp.length() == 1)
					sb.append("0");
				sb.append(tmp);
			} else {
				sb.append(c);
			}
		}
		return (new String(sb));
	}
	public static String unicode2UnicodeEsc(String uniStr)
    {
        StringBuffer ret = new StringBuffer();
        if(uniStr == null)
        {
            return null;
        }
        int maxLoop = uniStr.length();
        for(int i = 0; i < maxLoop; i++)
        {
            char character = uniStr.charAt(i);
            if(character <= '\177')
            {
                ret.append(character);
            } else
            {
                ret.append("\\u");
                String hexStr = Integer.toHexString(character);
                int zeroCount = 4 - hexStr.length();
                for(int j = 0; j < zeroCount; j++)
                {
                    ret.append('0');
                }

                ret.append(hexStr);
            }
        }

        return ret.toString();
    }

    public static String unicode2UnicodeEscWithoutComment(String uniStr) throws IOException {
        StringBuffer buf = new StringBuffer();
        BufferedReader reader = new BufferedReader(new StringReader(uniStr));
        boolean continueFlg = false;
        for(String line = null; (line = reader.readLine()) != null;)
        {
            if((line.trim().startsWith("#") || line.trim().startsWith("!")) && !continueFlg)
            {
                buf.append(line);
            } else
            {
                if(line.endsWith("\\"))
                {
                    continueFlg = true;
                } else
                {
                    continueFlg = false;
                }
                buf.append(unicode2UnicodeEsc(line));
            }
            buf.append("\n");
        }

        if(!uniStr.endsWith("\n"))
        {
            buf.deleteCharAt(buf.length() - 1);
        }
        return buf.toString();
    }
    /**
     *
     * @param sp 原字符串
     * @param sp1 要装换的字符串
     * @param sp2 目标字符串
     * @return
     */
    public static String textarea(String sp,String sp1,String sp2){
    	String sTemp = sp;
		String str = "";
		if (sp == null || sp.equals("")) {
			return str;
		}
		try {
			int iIndex = sTemp.indexOf(sp1);
			int iStar = 0;
			while (iIndex != -1) {
				String s1 = sTemp.substring(iStar, iIndex);
				if (iIndex < sTemp.length()) {
					sTemp = sTemp.substring(iIndex + 1, sTemp.length());
					s1 = s1 + sp2;
					str = str + s1;
					iIndex = sTemp.indexOf(sp1);
				}
			}
			str = str + sTemp;
		} catch (Exception e) {
		}
		return str;
    }
    /**
     * 统计数组中的相同字符串的最大相同数
     * @param srcs
     * @return
     */
    public static int findMaxSameCount(String[] srcs){
    	int maxSameCount=0;
    	Map<String, Integer> sames=new HashMap<String, Integer>();
    	for(int i=0;i<srcs.length;i++){
    		for(int j=i+1;j<srcs.length;j++){
    			if(srcs[j].equals(srcs[i])){
    				Integer sameCount=(Integer)sames.get(srcs[i]);
    				if(sameCount==null){
    					sameCount=new Integer(1);
    				}else{
    					sameCount=new Integer(sameCount.intValue()+1);
    				}
    				sames.put(srcs[i],sameCount);
    				if(maxSameCount<sameCount.intValue())
    					maxSameCount=sameCount.intValue();
    			}
    		}
    	}
    	return maxSameCount;
    }
    static final byte[] HEX_CHAR_TABLE = {
        (byte)'0', (byte)'1', (byte)'2', (byte)'3',
        (byte)'4', (byte)'5', (byte)'6', (byte)'7',
        (byte)'8', (byte)'9', (byte)'a', (byte)'b',
        (byte)'c', (byte)'d', (byte)'e', (byte)'f'
      };

    public static String getHexString(byte[] raw) throws UnsupportedEncodingException
      {
        byte[] hex = new byte[2 * raw.length];
        int index = 0;

        for (byte b : raw) {
          int v = b & 0xFF;
          hex[index++] = HEX_CHAR_TABLE[v >>> 4];
          hex[index++] = HEX_CHAR_TABLE[v & 0xF];
        }
        return new String(hex, "ASCII");
      }

    /**
     * 将string转为html格式的string<br>
     * 例如："\"你好Tom\",他见到Tom时大方的说<一个故事：99页>"<br>
     * 将转为：&quot;你好Tom&quot;,他见到Tom时大方的说&lt;一个故事：99页&gt;
     * @param s 原字符串
     * @return 转换后的字符串
     */
    public static final String escapeHTML(String s) {
		if (s == null)
			return null;
		StringBuffer sb = new StringBuffer();
		int n = s.length();
		for (int i = 0; i < n; i++) {
			char c = s.charAt(i);
			switch (c) {
			case '<':
				sb.append("&lt;");
				break;
			case '>':
				sb.append("&gt;");
				break;
			case '&':
				sb.append("&amp;");
				break;
			case '"':
				sb.append("&quot;");
				break;
			// be carefull with this one (non-breaking whitee space)
//			case ' ':
//				sb.append("&nbsp;");
//				break;

			default:
				sb.append(c);
				break;
			}
		}
		return sb.toString();
	}
    /**
	 * 将原字符串中的html转义字符转换为html实体 如："&lt;input name=&quot;user&quot;&gt;" 结果：<input name="user">
	 *
	 * @param source
	 *            原字符串
	 * @param start
	 *            开始位置
	 * @return 转换后的字符串
	 */
    public static final String unescapeHTML(String source, int start){
    	if(source==null) return null;
        int i,j;
        i = source.indexOf("&", start);
        if (i > -1) {
           j = source.indexOf(";" ,i);
           if (j > i) {
              String entityToLookFor = source.substring(i , j + 1);
              String value = (String)htmlEntities.get(entityToLookFor);
              if (value != null) {
                source = new StringBuffer().append(source.substring(0 , i))
                                      .append(value)
                                      .append(source.substring(j + 1))
                                      .toString();
              }
              return unescapeHTML(source, i + 1); // recursive call
            }
        }
        return source;
     }
    public static boolean isEmptyOrNull(String str)  {
      return ((str == null) || (str.length() == 0));
    }

    public static Object emptyToNull(String val) {
      return emptyToDefault(val, null);
    }

    public static Object nullToEmpty(Object val)  {
      return emptyToDefault(val, "");
    }

    public static Object emptyToDefault(Object val, String defaultValue)  {      
      if ((val == null))
        return defaultValue;
      return val;
    }

    public static String lowerCaseUnderlineToCamelCase(String name)  {
      StringBuffer newName = new StringBuffer();
      boolean nextIsUpper = false;

      name = name.toLowerCase();

      for (int i = 0; i < name.length(); ++i)   {
        if (name.charAt(i) == '_') {
          nextIsUpper = true;
        }
        else {
          newName.append((nextIsUpper) ? Character.toUpperCase(name.charAt(i)) : name.charAt(i));

          nextIsUpper = false;
        }
      }
      return newName.toString();
    }

    public static String camelCaseToLowerCaseUnderline(String name)  {
      StringBuffer newName = new StringBuffer();

      for (int i = 0; i < name.length(); ++i)
        if (Character.isUpperCase(name.charAt(i))) {
          if (i == 0)
            newName.append(Character.toLowerCase(name.charAt(i)));
          else
            newName.append("_").append(Character.toLowerCase(name.charAt(i)));
        }
        else
          newName.append(name.charAt(i));

      return newName.toString();
    }

    public static String upperCaseUnderlineToCamelCase(String name) {
      return lowerCaseUnderlineToCamelCase(name);
    }

    public static String camelCaseToUpperCaseUnderline(String name) {
      StringBuffer newName = new StringBuffer();

      for (int i = 0; i < name.length(); ++i)
        if (Character.isUpperCase(name.charAt(i)))
        {
          if (i == 0)
            newName.append(Character.toUpperCase(name.charAt(i)));
          else
            newName.append("_").append(Character.toUpperCase(name.charAt(i)));
        }
        else
          newName.append(Character.toUpperCase(name.charAt(i)));

      return newName.toString();
    }

    public static String toString(Object[] objects) {
      int i;
      String str = "";

      if (objects != null)
        for (i = 0; i < objects.length; ++i)
          str = str + "[" + objects[i] + "]" + ((i < objects.length - 1) ? ", " : "");

      return str;
    }
    /**
	 * 将字符串的第一个字母转换为大写
	 * @param src -原始字符串
	 * @return 第一个字母大写(如果是字母)的字符串
	 */
	public static String upperCaseFirstAlpha(String src){
		if(org.apache.commons.lang.StringUtils.isEmpty(src))
			return src;
		String firstAlpha=org.apache.commons.lang.StringUtils.upperCase(String.valueOf(src.charAt(0)));
		if(src.length()==1)
			return firstAlpha;
		return firstAlpha+src.substring(1);
	}
	/**
	 * 将字符串的第一个字母转换为小写
	 * @param src -原始字符串
	 * @return 第一个字母小写写(如果是字母)的字符串
	 */
	public static String lowerCaseFirstAlpha(String src){
		if(org.apache.commons.lang.StringUtils.isEmpty(src))
			return src;
		String firstAlpha=org.apache.commons.lang.StringUtils.lowerCase(String.valueOf(src.charAt(0)));
		if(src.length()==1)
			return firstAlpha;
		return firstAlpha+src.substring(1);
	}
	public static boolean parseBoolean(String booleanString){		
		return (booleanString==null||booleanString.equals(""))||(booleanString!=null?booleanString.equalsIgnoreCase("yes")||booleanString.equalsIgnoreCase("Y")
		||booleanString.equalsIgnoreCase("1")||booleanString.equalsIgnoreCase("true"):false);
	}
	public static String compressHtml(String html){		
		html=html.replaceAll("(?s)[ \\t]{2,}", " ");
		html=html.replaceAll("(?m)\\p{Space}+<", "<");
		html=html.replaceAll("(?m)\n\\p{Space}+\n", "\n");
		html=html.replaceAll("(?m)>\\p{Space}+<", "><");
		html=html.replaceAll("(?m)\\{\\p{Space}+", "\\{");
		html=html.replaceAll("(?m)\\p{Space}+\\}", "\\}");
		return html;
		
	}
	public static void main(String[] sd) throws Exception {
		System.out.println(StringTools.hideLatinCharacters(" ''''''"));
		String gbk="你奶";
		String ascii=convert(gbk);
		System.out.println(ascii);
		System.out.println(unicode2UnicodeEsc(gbk));
		System.out.println(unicode2UnicodeEscWithoutComment(ascii));
		String str1=ascii;
	    Charset  cs   =Charset.forName("GB2312");
	    CharBuffer cb   =cs.decode(ByteBuffer.wrap(gbk.getBytes()));
	    java.io.PrintStream ps = new java.io.PrintStream(System.out, true, "gbk");
	    ps.println(cb);
	    byte[] byteArray = {  (byte)255, (byte)254, (byte)253,(byte)252, (byte)251, (byte)250};
	    System.out.println(StringTools.getHexString(byteArray));

	    System.out.println(escapeHTML("\"你好Tom\",他见到Tom时大方的说 <一个故事：99页>"));

	    ps = new java.io.PrintStream(System.out, true, "utf-8");
	    String test = "&lt;input name=&quot;user&quot;&gt;";
	    ps.println(unescapeHTML(test, 0));


	}
}
